﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;
using System.Reflection;
using Microsoft.SharePoint.WebControls;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Runtime.Serialization;
using System.Data;
using System.Xml;
using System.Threading;

namespace LookupFieldEntityPicker.CustomLookup
{
    [SharePointPermissionAttribute(SecurityAction.Demand, ObjectModel = true)]
    public class DEMOLookupPicker : SPFieldLookup
    {
        private bool _preventUpdate = false;

        public DEMOLookupPicker( SPFieldCollection fields, string fieldName) : base(fields, fieldName)
        {
        }

        public DEMOLookupPicker( SPFieldCollection fields, string typeName, string displayName): base(fields, typeName, displayName)
        {
        }

        
        public override object GetFieldValue(string value)
        {
            return base.GetFieldValue(value);
        }

        internal void SetNamedThreadData(string propertyName, string value)
        {
            Thread.SetData(Thread.GetNamedDataSlot(propertyName), value);
        }

        internal string GetNamedThreadData(string propertyName)
        {
            var value = Thread.GetData(Thread.GetNamedDataSlot(propertyName));
            if (value == null)
                return string.Empty;
            else
                return value.ToString();
        }

        private void SetSearchableFields()
        {
            string sarchableFields = GetNamedThreadData("SearchableFields");
            if (string.IsNullOrEmpty(sarchableFields))
            {
                Thread.FreeNamedDataSlot("SearchableFields");
                return;
            }
            SearchableFields = sarchableFields;
        }

      
        private void UpdateFieldSchema(string propertyName, string value)
        {
            if (string.IsNullOrEmpty(propertyName))
                return;

            XmlDocument schemaXml = new XmlDocument();
            schemaXml.LoadXml(SchemaXml);

            XmlNode property = schemaXml.DocumentElement.Attributes.GetNamedItem(propertyName);

            if (property == null)
            {
                var attribute = schemaXml.CreateAttribute(propertyName);
                attribute.Value = value;

                schemaXml.DocumentElement.Attributes.Append(attribute);
                SchemaXml = schemaXml.OuterXml;
            }
            else
            {
                if (property.NodeType == XmlNodeType.Attribute)
                {
                    property.Value = value;

                    SchemaXml = schemaXml.OuterXml;
                }
                else
                {
                    throw new XmlException("Current Node is not an attribute");
                }
            }
        }

        
        public string SearchableFields
        {
            get
            {
                string value = GetProperty("SearchableFields");

                return value;
            }
            set
            {

                UpdateFieldSchema("SearchableFields", value);
            }
        }

       
        public override void OnAdded(SPAddFieldOptions op) 
        {
            this._preventUpdate = true;

            SetSearchableFields();
           
            this.Update();
        }

        public override void OnUpdated() 
        {
            if (!this._preventUpdate)
            {
                this._preventUpdate = true;

                SetSearchableFields();

                this.Update();
            }
        }


        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl fieldControl = new RecordLookupFieldControl() { FieldName = InternalName };
                return fieldControl;
            }
        }
    }
  
}
